#include "stdafx.h"
#include "CombatSysP.h"
#include "CombatSkill.h"
#include "Entity/EntityIf.h"
#include "Entity/LevelFunc.h"
#include "Entity/EvtEntity.h"

#include "States/CombatState_Casting.h"
#include "States/CombatState_Charging.h"
#include "States/CombatState_CoolDown.h"
#include "States/CombatState_Forbidden.h"
#include "States/CombatState_Peace.h"
#include "States/CombatState_Ready.h"
#include "States/CombatState_Standby.h"



//
//	Combat Data for Role
//

CombatSysP::CombatSysP()
:m_wpTheMainSkill(NULL), m_wpCurUntargetSkill(NULL)
{
	m_nFaction = Combat::FC_Player;

	memset(m_nExpForProps, 0, sizeof(m_nExpForProps));

#ifdef _DEBUG
	MoR = 1;
#endif
}


bool
CombatSysP::onInit(IGeneCreateData& createData)
{
	if (__super::onInit(createData))
	{
		return initState(Combat::CBS_Casting, new CombatState_Casting) &&
			initState(Combat::CBS_Ready, new CombatState_Ready) &&
			initState(Combat::CBS_Forbidden, new CombatState_Forbidden) &&
			initState(Combat::CBS_Peace, new CombatState_Peace_R) &&
			initState(Combat::CBS_CoolDown,new CombatState_CoolDown) &&
			initState(Combat::CBS_Charging, new CombatState_Charging) &&
			initState(Combat::CBS_Standby, new CombatState_Standby);


		return true;
	}
	else
	{
		return false;
	}
}

void 
CombatSysP::onEvent_CastPrep(IEvt& evt)
{
	if (isCalculator())
	{
		GECastPrep* pGE = dynamic_cast<GECastPrep*>(&evt);
		if (pGE!=NULL)
		{
			if (pGE->m_nType==GECastPrep::Main)
			{
				m_wpTheMainSkill = pGE->m_wpSkill;
				pGE->setDataY(CombatResult::Succeed);
			}
			else
			{
				if (pGE->m_wpSkill->m_nTarget==Combat::Tgt_Enemy ||
					pGE->m_wpSkill->m_nTarget==Combat::Tgt_EnemyInRange)
				{
					if (hasTargetCE())
					{
						m_thePendingAbilities.push_back(SkillWithTarget(getTargetCE_ID(), pGE->m_wpSkill));
						pGE->setDataY(CombatResult::Succeed);
					}
					else
					{
						pGE->setDataY(CombatResult::NoTarget);
					}
				}
				else if (pGE->m_wpSkill->m_nTarget==Combat::Tgt_Self)
				{
					m_thePendingAbilities.push_back(SkillWithTarget(m_wpHost->getID(), pGE->m_wpSkill));
					pGE->setDataY(CombatResult::Succeed);
				}
				else if (pGE->m_wpSkill->m_nTarget==Combat::Tgt_Alies ||
					pGE->m_wpSkill->m_nTarget==Combat::Tgt_AliesAndSelf)
				{
					if (m_wpCurUntargetSkill)
					{
						LOG_WARN("Problem, One spell still not find target , another spell cames!\n");
						pGE->setDataY(CombatResult::Busy);
					}
					else
					{
						m_wpCurUntargetSkill = pGE->m_wpSkill;
						pGE->setDataY(CombatResult::Targeting);
					}
				}
				else
				{
					LOG_ERROR_V("Failed to cast prep, invalid spell target, S%d, T%d!\n", pGE->m_wpSkill->m_nID, pGE->m_wpSkill->m_nTarget);
					pGE->setDataY(CombatResult::NoTarget);
				}
			}
		}
	}
}

void 
CombatSysP::onEvent_Target(IEvt& evt)
{
	GETarget* pGE = static_cast<GETarget*>(&evt);

	if (m_wpCurUntargetSkill)
	{
		if (m_wpCurUntargetSkill->m_nTarget==Combat::Tgt_AliesAndSelf ||
			m_wpCurUntargetSkill->m_nTarget==Combat::Tgt_Alies)
		{
			if (pGE->m_wpTarget->getFaction()==getFaction())
			{
				m_thePendingAbilities.push_back(SkillWithTarget(pGE->m_wpTarget->getID(), m_wpCurUntargetSkill));
				m_wpCurUntargetSkill = NULL;
				pGE->m_bTargeted = true;
			}
			else
			{
				//	Target is not what i want
			}
			return;
		}
		else
		{
			LOG_ERROR("Failed to valid ability in when doing targeting!\n");
		}
	}
	else if (getTargetCE_ID()!=pGE->m_wpTarget->getID())
	{
		if ( pGE->m_wpTarget->getFaction()!=getFaction())
		{
			setTargetCE(pGE->m_wpTarget->getID());
			pGE->m_bTargeted = true;


			if ( !pGE->m_bNotified && isCalculator() )
			{
				//
				//	Send a request to server
				//
				sendMsg_CbtTargt(*pGE->m_wpTarget);
			}
		}
		else
		{
			LOG_WARN("Failed, try to set an alies as enemy!\n");
		}
	}


	//
	//	If the main role is not in combat status
	//
}


//
//	Calculator or Demonstrator
bool CombatSysP::isCalculator()const
{
	return  true; //m_wpHost!=NULL ? m_wpHost->isMe(): false;
}


bool
CombatSysP::TryCastNewSpell()
{
	CombatSkill* pSkill = NULL;
	IEntity* pTarget = NULL;

	if (!hasFlg(Combat::FIdx_Daze) &&
		!m_thePendingAbilities.empty())
	{
		pSkill = m_thePendingAbilities.front().m_wpSkill;
		pTarget = getTarget(m_thePendingAbilities.front().m_nTargetID);
		m_thePendingAbilities.pop_front();
	}
	else
	{
		pSkill = m_wpTheMainSkill;
		if (pSkill!=NULL)
		{
			pTarget = getTargetCE();
		}
	}

	if (pSkill!=NULL && pTarget!=0)
	{
		//
		//	Check whether there is enough energy for casting the next spell
		//
		if (getMP()>=pSkill->m_nEnergeCost)
		{
			return sendMsg_CbtStart( *pTarget, *pSkill);
		}
		else
		{
			return false;
		}
	}

	return false;
}

#ifdef _DEBUG
const char*
CombatSysP::getCombatTag()const
{
	return "P";
}
#endif





